package com.open.validator.impl;

import com.open.validator.PatternExt;
import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.validator.internal.engine.messageinterpolation.util.InterpolationHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;

/**
 * @author: system
 * @Date: 2024/4/19 15:10
 * @Version: V1.0
 * @description: desc:
 */

public class PatternExtValidator implements ConstraintValidator<PatternExt, Object> {

    private static final Logger log = LoggerFactory.getLogger(PatternExtValidator.class);

    private java.util.regex.Pattern pattern;
    private String escapedRegexp;
    private String field;
    private String depField;
    private String[] depValue;

    @Override
    public void initialize(PatternExt parameters) {
        PatternExt.Flag[] flags = parameters.flags();
        int intFlag = 0;
        for (PatternExt.Flag flag : flags) {
            intFlag = intFlag | flag.getValue();
        }

        try {
            pattern = java.util.regex.Pattern.compile(parameters.regexp(), intFlag);
        } catch (PatternSyntaxException e) {
            throw e;
        }

        escapedRegexp = InterpolationHelper.escapeMessageParameter(parameters.regexp());
        field = parameters.field();
        depField = parameters.depField();
        depValue = parameters.depValue();
    }

    /**
     * field,depField,depValue三个属性其一为null值，不进行校验；<br>
     * 约束字段的值和依赖字段的值其一为null值，不进行校验；<br>
     * depValue不等于依赖字段的值，不进行校验
     */
    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        if (object == null) {
            return true;
        }


        try {

            if (object == null || field == null || depField == null || depValue == null) {
                return true;
            }

            Object checkedValue = BeanUtils.getProperty(object, field);
            if (checkedValue == null) {
                return true;
            }

            Object requiredValue = BeanUtils.getProperty(object, depField);
            if (requiredValue == null) {
                return true;
            }

            if (depValue.length <= 0 || Arrays.asList(depValue).contains(requiredValue)) {
                Matcher m = pattern.matcher((CharSequence) checkedValue);
                return m.matches();
            } else {
                return true;
            }

        } catch (IllegalAccessException e) {
            log.error("Accessor method is not available for class : {}, exception : {}", object.getClass().getName(),
                    e);
            return false;
        } catch (NoSuchMethodException e) {
            log.error("Field or method is not present on class : {}, exception : {}", object.getClass().getName(), e);
            return false;
        } catch (InvocationTargetException e) {
            log.error("An exception occurred while accessing class : {}, exception : {}", object.getClass().getName(),
                    e);
            return false;
        }

    }

}
